package betterScreen;

import java.awt.DisplayMode;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

//buffering: prevent flickering by drawing to buffer, then making visible
public class ScreenManager {
    
    private GraphicsDevice vc; //video card
    
    //gives vc access to monitor
    public ScreenManager() {
	GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
	vc = e.getDefaultScreenDevice();
    }
    
    //note: this is retarded. external reference?
    //get all compatible Display Modes
    public DisplayMode[] getCompatibleDisplayModes() {
	return vc.getDisplayModes();
    }
    
    //compares DM passed in to vc display modes and see if they match
    public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) { //probably merge this with getcompatible
	DisplayMode goodModes[] = vc.getDisplayModes();
	for(int i=0;i<modes.length;i++) {
	    for(int j = 0; j<goodModes.length;j++) {
		if (displayModesMatch(modes[i], goodModes[j])) {
		    return modes[i];
		}
	    }
	}
	return null;
    }
    
    //get current DM; this method is also terribly, terribly wasteful
    public DisplayMode getCurrentDisplayMode() {
	return vc.getDisplayMode();
    }
    
    //checks if 2 modes match eachother
    public boolean displayModesMatch(DisplayMode firstMode, DisplayMode secondMode) {
	if (firstMode.getWidth() != secondMode.getWidth() || firstMode.getHeight() != secondMode.getHeight()) {
	    return false;
	}
	if (firstMode.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && 
		secondMode.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && 
		firstMode.getBitDepth() != secondMode.getBitDepth()) {
	    return false;
	}
	if (firstMode.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && 
		secondMode.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && 
		firstMode.getRefreshRate() != secondMode.getRefreshRate()) {
	    return false;
	}
	return true;
    }
    
    //make frame fullscreen
    public void setFullScreen(DisplayMode dm) {
	JFrame f = new JFrame();
	f.setUndecorated(true);
	f.setIgnoreRepaint(true);
	f.setResizable(false);
	vc.setFullScreenWindow(f);
	
	if (dm!= null && vc.isDisplayChangeSupported()) {
	    try{
		vc.setDisplayMode(dm);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}
	f.createBufferStrategy(2);
    }
    
    //retrive graphics object for buffered strategy
    public Graphics2D getGraphics() {
	Window w = vc.getFullScreenWindow();
	if (w != null) {
	    BufferStrategy s = w.getBufferStrategy();
	    return(Graphics2D) s.getDrawGraphics();
	} else {
	    return null;
	}
    }
    
    //updates display
    public void update() {
	Window w = vc.getFullScreenWindow();
	if(w != null) {
	    BufferStrategy bs = w.getBufferStrategy();
	    if (!bs.contentsLost()) {
		bs.show();
	    }
	}
    }
    
   
    public int getWidth() {
	Window w = vc.getFullScreenWindow();
	if (w != null) {
	    return w.getWidth();
	} else {
	    return 0;
	}
    }
    
    public int getHeight() {
	Window w = vc.getFullScreenWindow();
	if (w != null) {
	    return w.getHeight();
	} else {
	    return 0;
	}
    }
    
    //exit fullscreen
    public void restoreScreen() {
	Window w = vc.getFullScreenWindow();
	if (w != null) {
	    w.dispose();
	}
	vc.setFullScreenWindow(null);
    }
    
    //create image compatible with monitor
    public BufferedImage createCompatibleImage(int w, int h, int t) {
	Window win = vc.getFullScreenWindow();
	if(win != null) {
	    GraphicsConfiguration gc = win.getGraphicsConfiguration();
	    return gc.createCompatibleImage(w,  h, t);
	}
	return null;
    }
    
    
}
